<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>Fielddata 的过滤 | Elasticsearch: 权威指南 | Elastic</title>
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
</head>
<body>
<div class="main-container">
    <section id="content">
        
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原文地址: <a href="https://www.elastic.co/guide/cn/elasticsearch/guide/current/_fielddata_filtering.html" rel="nofollow">https://www.elastic.co/guide/cn/elasticsearch/guide/current/_fielddata_filtering.html</a>, 版权归 www.elastic.co 所有<br/>
                            英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/guide/current/_fielddata_filtering.html" rel="nofollow">https://www.elastic.co/guide/en/elasticsearch/guide/current/_fielddata_filtering.html</a>
                            </div>
                        <!-- start body -->
                  <div class="page_header">
<b>请注意:</b><br>本书基于 Elasticsearch 2.x 版本，有些内容可能已经过时。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch: 权威指南</a></span>
»
<span class="breadcrumb-link"><a href="aggregations.html">聚合</a></span>
»
<span class="breadcrumb-link"><a href="docvalues-and-fielddata.html">Doc Values and Fielddata</a></span>
»
<span class="breadcrumb-node">fielddata 过滤</span>
</div>
<div class="navheader">
<span class="prev">
<a href="_limiting_memory_usage.html">« 限制内存使用</a>
</span>
<span class="next">
<a href="preload-fielddata.html">预加载 fielddata »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="_fielddata_filtering"></a>fielddata 过滤 (<code class="literal">fielddata filter</code>)<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elasticsearch-cn/elasticsearch-definitive-guide/edit/cn/300_Aggregations/105_filtering.asciidoc">edit</a>
</h2>
</div></div></div>
<p>设想我们正在运行一个网站允许用户收听他们喜欢的歌曲。
为了让他们可以更容易的管理自己的音乐库，用户可以为歌曲设置任何他们喜欢的标签，这样我们就会有很多歌曲被附上 <code class="word">rock（摇滚）</code> 、 <code class="word">hiphop（嘻哈）</code> 和 <code class="word">electronica（电音）</code> ，但也会有些歌曲被附上 <code class="word">my_16th_birthday_favorite_anthem</code> 这样的标签。</p>

<p>现在设想我们想要为用户展示每首歌曲最受欢迎的三个标签，很有可能 <code class="word">rock</code> 这样的标签会排在三个中的最前面，而 <code class="word">my_16th_birthday_favorite_anthem</code> 则不太可能得到评级。
尽管如此，为了计算最受欢迎的标签，我们必须强制将这些一次性的词项(term) 加载到内存中。</p>

<p>得益于 fielddata 过滤，我们可以控制这种状况。我们 <em>知道</em> 自己只对最流行的词项(term)感兴趣，所以我们可以简单地避免加载那些不太有意思的长尾项：</p>
<div class="pre_wrapper lang-js">
<pre class="programlisting prettyprint lang-js">PUT /music/_mapping/song
{
  "properties": {
    "tag": {
      "type": "string",
      "fielddata": { <a id="CO220-1"></a><i class="conum" data-value="1"></i>
        "filter": {
          "frequency": { <a id="CO220-2"></a><i class="conum" data-value="2"></i>
            "min":              0.01, <a id="CO220-3"></a><i class="conum" data-value="3"></i>
            "min_segment_size": 500  <a id="CO220-4"></a><i class="conum" data-value="4"></i>
          }
        }
      }
    }
  }
}</pre>
</div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO220-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p><code class="literal">fielddata</code> 关键字允许我们配置 fielddata 处理该分段的方式。</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO220-2"><i class="conum" data-value="2"></i></a></p>
</td>
<td align="left" valign="top">
<p><code class="literal">frequency</code> 过滤器允许我们基于项频率过滤加载 fielddata。</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO220-3"><i class="conum" data-value="3"></i></a></p>
</td>
<td align="left" valign="top">
<p>只加载那些至少在本分段文档中出现 1% 的项。</p>
</td>
</tr>
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO220-4"><i class="conum" data-value="4"></i></a></p>
</td>
<td align="left" valign="top">
<p>忽略任何文档个数小于 500 的 分段(segment)。</p>
</td>
</tr>
</table>
</div>
<p>有了这个映射，只有那些至少在 <em>本分段</em> 文档中出现超过 1% 的项才会被加载到内存中。我们也可以指定一个 <code class="literal">最大</code> 词频(term frequency)，它可以被用来排除 <em>太常用</em> 的词项(term)，比如 <a class="xref" href="stopwords.html" title="停用词: 性能与精度">停用词(stopword)</a> 。</p>

<p>这种情况下，词频是按照分段来计算的。这是实现的一个限制：fielddata 是按分段来加载的，所以可见的词频只是该分段内的频率。但是，这个限制也有些有趣的特性：它可以让新的受欢迎的词项(term)迅速提升到顶部。</p>

<p>比如一个新风格的歌曲在一夜之间受大众欢迎，我们可能想要将这种新风格的歌曲标签包括在最受欢迎列表中，但如果我们仍通过对索引做完整的计算来获取词频，我们就必须等到新标签变得像 <code class="word">rock</code> 和 <code class="word">electronica</code> ）一样流行。
由于频率过滤方式得以实现，新加的标签会很快作为高频标签出现在新分段内，也当然会迅速上升到顶部。</p>

<p><code class="literal">min_segment_size</code> 参数要求 Elasticsearch 忽略某个大小以下的分段。 如果一个分段内只有少量文档，它的词频会非常粗略, 而没有任何意义。
小的分段会很快被合并到更大的分段中，这样就足够大而被计入统计数据。</p>
<div class="tip admon">
<div class="icon"></div>
<div class="admon_content">
<p>通过频率来过滤词项并不是唯一的选择，我们也可以使用正则表达式来决定只加载那些匹配的项。例如，我们可以用 <code class="literal">regex</code> 过滤器 处理 twitte 上的消息只将以 <code class="literal">#</code> 号开始的标签加载到内存中。
前提是假设我们使用的分析器会保留标点符号，像 <code class="literal">whitespace</code> 分析器。</p>
</div>
</div>
<p>Fielddata 过滤对内存使用有 <em>巨大的</em> 影响。这种取舍很明显的特点是：我们实际上是在忽略数据。但对于很多应用，这种取舍是合理的，因为这些数据根本就没有被使用到。内存的节省通常要比包括大量而无用的长尾词项(long tail term)更为重要。</p>
</div>
<div class="navfooter">
<span class="prev">
<a href="_limiting_memory_usage.html">« 限制内存使用</a>
</span>
<span class="next">
<a href="preload-fielddata.html">预加载 fielddata »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>